package permission_pb

import (
	context "context"
	fmt "fmt"
	gorm1 "github.com/infobloxopen/atlas-app-toolkit/gorm"
	query "github.com/infobloxopen/atlas-app-toolkit/query"
	errors "github.com/infobloxopen/protoc-gen-gorm/errors"
	types "github.com/infobloxopen/protoc-gen-gorm/types"
	gorm "github.com/jinzhu/gorm"
	pq "github.com/lib/pq"
	go_uuid "github.com/satori/go.uuid"
	field_mask "google.golang.org/genproto/protobuf/field_mask"
	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
	strings "strings"
	time "time"
)

type UserORM struct {
	ActiveColor  string
	AuthorityIds pq.Int64Array `gorm:"type:integer[]"`
	BaseColor    string        `gorm:"default:#fff"`
	CreatedAt    *time.Time
	Email        string
	HeaderImg    string `gorm:"default:ttps://qmplusimg.henrongyi.top/gva_header.jpg"`
	Id           uint64
	NickName     string `gorm:"default:系统用户"`
	Password     string
	Phone        string
	SideMode     string       `gorm:"default:dark"`
	UUID         go_uuid.UUID `gorm:"type:uuid"`
	UpdatedAt    *time.Time
	Username     string
}

// TableName overrides the default tablename generated by GORM
func (UserORM) TableName() string {
	return "users"
}

// ToORM runs the BeforeToORM hook if present, converts the fields of this
// object to ORM format, runs the AfterToORM hook, then returns the ORM object
func (m *User) ToORM(ctx context.Context) (UserORM, error) {
	to := UserORM{}
	var err error
	if prehook, ok := interface{}(m).(UserWithBeforeToORM); ok {
		if err = prehook.BeforeToORM(ctx, &to); err != nil {
			return to, err
		}
	}
	to.Id = m.Id
	if m.CreatedAt != nil {
		t := m.CreatedAt.AsTime()
		to.CreatedAt = &t
	}
	if m.UpdatedAt != nil {
		t := m.UpdatedAt.AsTime()
		to.UpdatedAt = &t
	}
	to.Username = m.Username
	to.Password = m.Password
	to.NickName = m.NickName
	to.SideMode = m.SideMode
	to.HeaderImg = m.HeaderImg
	to.BaseColor = m.BaseColor
	to.ActiveColor = m.ActiveColor
	to.Phone = m.Phone
	to.Email = m.Email
	if m.AuthorityIds != nil {
		to.AuthorityIds = make(pq.Int64Array, len(m.AuthorityIds))
		copy(to.AuthorityIds, m.AuthorityIds)
	}
	if m.UUID != nil {
		to.UUID, err = go_uuid.FromString(m.UUID.Value)
		if err != nil {
			return to, err
		}
	} else {
		to.UUID = go_uuid.Nil
	}
	if posthook, ok := interface{}(m).(UserWithAfterToORM); ok {
		err = posthook.AfterToORM(ctx, &to)
	}
	return to, err
}

// ToPB runs the BeforeToPB hook if present, converts the fields of this
// object to PB format, runs the AfterToPB hook, then returns the PB object
func (m *UserORM) ToPB(ctx context.Context) (User, error) {
	to := User{}
	var err error
	if prehook, ok := interface{}(m).(UserWithBeforeToPB); ok {
		if err = prehook.BeforeToPB(ctx, &to); err != nil {
			return to, err
		}
	}
	to.Id = m.Id
	if m.CreatedAt != nil {
		to.CreatedAt = timestamppb.New(*m.CreatedAt)
	}
	if m.UpdatedAt != nil {
		to.UpdatedAt = timestamppb.New(*m.UpdatedAt)
	}
	to.Username = m.Username
	to.Password = m.Password
	to.NickName = m.NickName
	to.SideMode = m.SideMode
	to.HeaderImg = m.HeaderImg
	to.BaseColor = m.BaseColor
	to.ActiveColor = m.ActiveColor
	to.Phone = m.Phone
	to.Email = m.Email
	if m.AuthorityIds != nil {
		to.AuthorityIds = make(pq.Int64Array, len(m.AuthorityIds))
		copy(to.AuthorityIds, m.AuthorityIds)
	}
	to.UUID = &types.UUID{Value: m.UUID.String()}
	if posthook, ok := interface{}(m).(UserWithAfterToPB); ok {
		err = posthook.AfterToPB(ctx, &to)
	}
	return to, err
}

// The following are interfaces you can implement for special behavior during ORM/PB conversions
// of type User the arg will be the target, the caller the one being converted from

// UserBeforeToORM called before default ToORM code
type UserWithBeforeToORM interface {
	BeforeToORM(context.Context, *UserORM) error
}

// UserAfterToORM called after default ToORM code
type UserWithAfterToORM interface {
	AfterToORM(context.Context, *UserORM) error
}

// UserBeforeToPB called before default ToPB code
type UserWithBeforeToPB interface {
	BeforeToPB(context.Context, *User) error
}

// UserAfterToPB called after default ToPB code
type UserWithAfterToPB interface {
	AfterToPB(context.Context, *User) error
}

// DefaultCreateUser executes a basic gorm create call
func DefaultCreateUser(ctx context.Context, in *User, db *gorm.DB) (*User, error) {
	if in == nil {
		return nil, errors.NilArgumentError
	}
	ormObj, err := in.ToORM(ctx)
	if err != nil {
		return nil, err
	}
	if hook, ok := interface{}(&ormObj).(UserORMWithBeforeCreate_); ok {
		if db, err = hook.BeforeCreate_(ctx, db); err != nil {
			return nil, err
		}
	}
	if err = db.Create(&ormObj).Error; err != nil {
		return nil, err
	}
	if hook, ok := interface{}(&ormObj).(UserORMWithAfterCreate_); ok {
		if err = hook.AfterCreate_(ctx, db); err != nil {
			return nil, err
		}
	}
	pbResponse, err := ormObj.ToPB(ctx)
	return &pbResponse, err
}

type UserORMWithBeforeCreate_ interface {
	BeforeCreate_(context.Context, *gorm.DB) (*gorm.DB, error)
}
type UserORMWithAfterCreate_ interface {
	AfterCreate_(context.Context, *gorm.DB) error
}

func DefaultReadUser(ctx context.Context, in *User, db *gorm.DB, fs *query.FieldSelection) (*User, error) {
	if in == nil {
		return nil, errors.NilArgumentError
	}
	ormObj, err := in.ToORM(ctx)
	if err != nil {
		return nil, err
	}
	if ormObj.Id == 0 {
		return nil, errors.EmptyIdError
	}
	if hook, ok := interface{}(&ormObj).(UserORMWithBeforeReadApplyQuery); ok {
		if db, err = hook.BeforeReadApplyQuery(ctx, db, fs); err != nil {
			return nil, err
		}
	}
	if db, err = gorm1.ApplyFieldSelection(ctx, db, fs, &UserORM{}); err != nil {
		return nil, err
	}
	if hook, ok := interface{}(&ormObj).(UserORMWithBeforeReadFind); ok {
		if db, err = hook.BeforeReadFind(ctx, db, fs); err != nil {
			return nil, err
		}
	}
	ormResponse := UserORM{}
	if err = db.Where(&ormObj).First(&ormResponse).Error; err != nil {
		return nil, err
	}
	if hook, ok := interface{}(&ormResponse).(UserORMWithAfterReadFind); ok {
		if err = hook.AfterReadFind(ctx, db, fs); err != nil {
			return nil, err
		}
	}
	pbResponse, err := ormResponse.ToPB(ctx)
	return &pbResponse, err
}

type UserORMWithBeforeReadApplyQuery interface {
	BeforeReadApplyQuery(context.Context, *gorm.DB, *query.FieldSelection) (*gorm.DB, error)
}
type UserORMWithBeforeReadFind interface {
	BeforeReadFind(context.Context, *gorm.DB, *query.FieldSelection) (*gorm.DB, error)
}
type UserORMWithAfterReadFind interface {
	AfterReadFind(context.Context, *gorm.DB, *query.FieldSelection) error
}

func DefaultDeleteUser(ctx context.Context, in *User, db *gorm.DB) error {
	if in == nil {
		return errors.NilArgumentError
	}
	ormObj, err := in.ToORM(ctx)
	if err != nil {
		return err
	}
	if ormObj.Id == 0 {
		return errors.EmptyIdError
	}
	if hook, ok := interface{}(&ormObj).(UserORMWithBeforeDelete_); ok {
		if db, err = hook.BeforeDelete_(ctx, db); err != nil {
			return err
		}
	}
	err = db.Where(&ormObj).Delete(&UserORM{}).Error
	if err != nil {
		return err
	}
	if hook, ok := interface{}(&ormObj).(UserORMWithAfterDelete_); ok {
		err = hook.AfterDelete_(ctx, db)
	}
	return err
}

type UserORMWithBeforeDelete_ interface {
	BeforeDelete_(context.Context, *gorm.DB) (*gorm.DB, error)
}
type UserORMWithAfterDelete_ interface {
	AfterDelete_(context.Context, *gorm.DB) error
}

func DefaultDeleteUserSet(ctx context.Context, in []*User, db *gorm.DB) error {
	if in == nil {
		return errors.NilArgumentError
	}
	var err error
	keys := []uint64{}
	for _, obj := range in {
		ormObj, err := obj.ToORM(ctx)
		if err != nil {
			return err
		}
		if ormObj.Id == 0 {
			return errors.EmptyIdError
		}
		keys = append(keys, ormObj.Id)
	}
	if hook, ok := (interface{}(&UserORM{})).(UserORMWithBeforeDeleteSet); ok {
		if db, err = hook.BeforeDeleteSet(ctx, in, db); err != nil {
			return err
		}
	}
	err = db.Where("id in (?)", keys).Delete(&UserORM{}).Error
	if err != nil {
		return err
	}
	if hook, ok := (interface{}(&UserORM{})).(UserORMWithAfterDeleteSet); ok {
		err = hook.AfterDeleteSet(ctx, in, db)
	}
	return err
}

type UserORMWithBeforeDeleteSet interface {
	BeforeDeleteSet(context.Context, []*User, *gorm.DB) (*gorm.DB, error)
}
type UserORMWithAfterDeleteSet interface {
	AfterDeleteSet(context.Context, []*User, *gorm.DB) error
}

// DefaultStrictUpdateUser clears / replaces / appends first level 1:many children and then executes a gorm update call
func DefaultStrictUpdateUser(ctx context.Context, in *User, db *gorm.DB) (*User, error) {
	if in == nil {
		return nil, fmt.Errorf("Nil argument to DefaultStrictUpdateUser")
	}
	ormObj, err := in.ToORM(ctx)
	if err != nil {
		return nil, err
	}
	lockedRow := &UserORM{}
	db.Model(&ormObj).Set("gorm:query_option", "FOR UPDATE").Where("id=?", ormObj.Id).First(lockedRow)
	if hook, ok := interface{}(&ormObj).(UserORMWithBeforeStrictUpdateCleanup); ok {
		if db, err = hook.BeforeStrictUpdateCleanup(ctx, db); err != nil {
			return nil, err
		}
	}
	if hook, ok := interface{}(&ormObj).(UserORMWithBeforeStrictUpdateSave); ok {
		if db, err = hook.BeforeStrictUpdateSave(ctx, db); err != nil {
			return nil, err
		}
	}
	if err = db.Save(&ormObj).Error; err != nil {
		return nil, err
	}
	if hook, ok := interface{}(&ormObj).(UserORMWithAfterStrictUpdateSave); ok {
		if err = hook.AfterStrictUpdateSave(ctx, db); err != nil {
			return nil, err
		}
	}
	pbResponse, err := ormObj.ToPB(ctx)
	if err != nil {
		return nil, err
	}
	return &pbResponse, err
}

type UserORMWithBeforeStrictUpdateCleanup interface {
	BeforeStrictUpdateCleanup(context.Context, *gorm.DB) (*gorm.DB, error)
}
type UserORMWithBeforeStrictUpdateSave interface {
	BeforeStrictUpdateSave(context.Context, *gorm.DB) (*gorm.DB, error)
}
type UserORMWithAfterStrictUpdateSave interface {
	AfterStrictUpdateSave(context.Context, *gorm.DB) error
}

// DefaultPatchUser executes a basic gorm update call with patch behavior
func DefaultPatchUser(ctx context.Context, in *User, updateMask *field_mask.FieldMask, db *gorm.DB) (*User, error) {
	if in == nil {
		return nil, errors.NilArgumentError
	}
	var pbObj User
	var err error
	if hook, ok := interface{}(&pbObj).(UserWithBeforePatchRead); ok {
		if db, err = hook.BeforePatchRead(ctx, in, updateMask, db); err != nil {
			return nil, err
		}
	}
	pbReadRes, err := DefaultReadUser(ctx, &User{Id: in.GetId()}, db, nil)
	if err != nil {
		return nil, err
	}
	pbObj = *pbReadRes
	if hook, ok := interface{}(&pbObj).(UserWithBeforePatchApplyFieldMask); ok {
		if db, err = hook.BeforePatchApplyFieldMask(ctx, in, updateMask, db); err != nil {
			return nil, err
		}
	}
	if _, err := DefaultApplyFieldMaskUser(ctx, &pbObj, in, updateMask, "", db); err != nil {
		return nil, err
	}
	if hook, ok := interface{}(&pbObj).(UserWithBeforePatchSave); ok {
		if db, err = hook.BeforePatchSave(ctx, in, updateMask, db); err != nil {
			return nil, err
		}
	}
	pbResponse, err := DefaultStrictUpdateUser(ctx, &pbObj, db)
	if err != nil {
		return nil, err
	}
	if hook, ok := interface{}(pbResponse).(UserWithAfterPatchSave); ok {
		if err = hook.AfterPatchSave(ctx, in, updateMask, db); err != nil {
			return nil, err
		}
	}
	return pbResponse, nil
}

type UserWithBeforePatchRead interface {
	BeforePatchRead(context.Context, *User, *field_mask.FieldMask, *gorm.DB) (*gorm.DB, error)
}
type UserWithBeforePatchApplyFieldMask interface {
	BeforePatchApplyFieldMask(context.Context, *User, *field_mask.FieldMask, *gorm.DB) (*gorm.DB, error)
}
type UserWithBeforePatchSave interface {
	BeforePatchSave(context.Context, *User, *field_mask.FieldMask, *gorm.DB) (*gorm.DB, error)
}
type UserWithAfterPatchSave interface {
	AfterPatchSave(context.Context, *User, *field_mask.FieldMask, *gorm.DB) error
}

// DefaultPatchSetUser executes a bulk gorm update call with patch behavior
func DefaultPatchSetUser(ctx context.Context, objects []*User, updateMasks []*field_mask.FieldMask, db *gorm.DB) ([]*User, error) {
	if len(objects) != len(updateMasks) {
		return nil, fmt.Errorf(errors.BadRepeatedFieldMaskTpl, len(updateMasks), len(objects))
	}

	results := make([]*User, 0, len(objects))
	for i, patcher := range objects {
		pbResponse, err := DefaultPatchUser(ctx, patcher, updateMasks[i], db)
		if err != nil {
			return nil, err
		}

		results = append(results, pbResponse)
	}

	return results, nil
}

// DefaultApplyFieldMaskUser patches an pbObject with patcher according to a field mask.
func DefaultApplyFieldMaskUser(ctx context.Context, patchee *User, patcher *User, updateMask *field_mask.FieldMask, prefix string, db *gorm.DB) (*User, error) {
	if patcher == nil {
		return nil, nil
	} else if patchee == nil {
		return nil, errors.NilArgumentError
	}
	var err error
	var updatedCreatedAt bool
	var updatedUpdatedAt bool
	for i, f := range updateMask.Paths {
		if f == prefix+"Id" {
			patchee.Id = patcher.Id
			continue
		}
		if !updatedCreatedAt && strings.HasPrefix(f, prefix+"CreatedAt.") {
			if patcher.CreatedAt == nil {
				patchee.CreatedAt = nil
				continue
			}
			if patchee.CreatedAt == nil {
				patchee.CreatedAt = &timestamppb.Timestamp{}
			}
			childMask := &field_mask.FieldMask{}
			for j := i; j < len(updateMask.Paths); j++ {
				if trimPath := strings.TrimPrefix(updateMask.Paths[j], prefix+"CreatedAt."); trimPath != updateMask.Paths[j] {
					childMask.Paths = append(childMask.Paths, trimPath)
				}
			}
			if err := gorm1.MergeWithMask(patcher.CreatedAt, patchee.CreatedAt, childMask); err != nil {
				return nil, nil
			}
		}
		if f == prefix+"CreatedAt" {
			updatedCreatedAt = true
			patchee.CreatedAt = patcher.CreatedAt
			continue
		}
		if !updatedUpdatedAt && strings.HasPrefix(f, prefix+"UpdatedAt.") {
			if patcher.UpdatedAt == nil {
				patchee.UpdatedAt = nil
				continue
			}
			if patchee.UpdatedAt == nil {
				patchee.UpdatedAt = &timestamppb.Timestamp{}
			}
			childMask := &field_mask.FieldMask{}
			for j := i; j < len(updateMask.Paths); j++ {
				if trimPath := strings.TrimPrefix(updateMask.Paths[j], prefix+"UpdatedAt."); trimPath != updateMask.Paths[j] {
					childMask.Paths = append(childMask.Paths, trimPath)
				}
			}
			if err := gorm1.MergeWithMask(patcher.UpdatedAt, patchee.UpdatedAt, childMask); err != nil {
				return nil, nil
			}
		}
		if f == prefix+"UpdatedAt" {
			updatedUpdatedAt = true
			patchee.UpdatedAt = patcher.UpdatedAt
			continue
		}
		if f == prefix+"Username" {
			patchee.Username = patcher.Username
			continue
		}
		if f == prefix+"Password" {
			patchee.Password = patcher.Password
			continue
		}
		if f == prefix+"NickName" {
			patchee.NickName = patcher.NickName
			continue
		}
		if f == prefix+"SideMode" {
			patchee.SideMode = patcher.SideMode
			continue
		}
		if f == prefix+"HeaderImg" {
			patchee.HeaderImg = patcher.HeaderImg
			continue
		}
		if f == prefix+"BaseColor" {
			patchee.BaseColor = patcher.BaseColor
			continue
		}
		if f == prefix+"ActiveColor" {
			patchee.ActiveColor = patcher.ActiveColor
			continue
		}
		if f == prefix+"Phone" {
			patchee.Phone = patcher.Phone
			continue
		}
		if f == prefix+"Email" {
			patchee.Email = patcher.Email
			continue
		}
		if f == prefix+"AuthorityIds" {
			patchee.AuthorityIds = patcher.AuthorityIds
			continue
		}
		if f == prefix+"UUID" {
			patchee.UUID = patcher.UUID
			continue
		}
	}
	if err != nil {
		return nil, err
	}
	return patchee, nil
}

// DefaultListUser executes a gorm list call
func DefaultListUser(ctx context.Context, db *gorm.DB, f *query.Filtering, s *query.Sorting, p *query.Pagination, fs *query.FieldSelection) ([]*User, error) {
	in := User{}
	ormObj, err := in.ToORM(ctx)
	if err != nil {
		return nil, err
	}
	if hook, ok := interface{}(&ormObj).(UserORMWithBeforeListApplyQuery); ok {
		if db, err = hook.BeforeListApplyQuery(ctx, db, f, s, p, fs); err != nil {
			return nil, err
		}
	}
	db, err = gorm1.ApplyCollectionOperators(ctx, db, &UserORM{}, &User{}, f, s, p, fs)
	if err != nil {
		return nil, err
	}
	if hook, ok := interface{}(&ormObj).(UserORMWithBeforeListFind); ok {
		if db, err = hook.BeforeListFind(ctx, db, f, s, p, fs); err != nil {
			return nil, err
		}
	}
	db = db.Where(&ormObj)
	db = db.Order("id")
	ormResponse := []UserORM{}
	if err := db.Find(&ormResponse).Error; err != nil {
		return nil, err
	}
	if hook, ok := interface{}(&ormObj).(UserORMWithAfterListFind); ok {
		if err = hook.AfterListFind(ctx, db, &ormResponse, f, s, p, fs); err != nil {
			return nil, err
		}
	}
	pbResponse := []*User{}
	for _, responseEntry := range ormResponse {
		temp, err := responseEntry.ToPB(ctx)
		if err != nil {
			return nil, err
		}
		pbResponse = append(pbResponse, &temp)
	}
	return pbResponse, nil
}

type UserORMWithBeforeListApplyQuery interface {
	BeforeListApplyQuery(context.Context, *gorm.DB, *query.Filtering, *query.Sorting, *query.Pagination, *query.FieldSelection) (*gorm.DB, error)
}
type UserORMWithBeforeListFind interface {
	BeforeListFind(context.Context, *gorm.DB, *query.Filtering, *query.Sorting, *query.Pagination, *query.FieldSelection) (*gorm.DB, error)
}
type UserORMWithAfterListFind interface {
	AfterListFind(context.Context, *gorm.DB, *[]UserORM, *query.Filtering, *query.Sorting, *query.Pagination, *query.FieldSelection) error
}
type UserServiceDefaultServer struct {
	DB *gorm.DB
}

// Register ...
func (m *UserServiceDefaultServer) Register(ctx context.Context, in *CreateUserRequest) (*CreateUserResponse, error) {
	out := &CreateUserResponse{}
	return out, nil
}

// GetUserByName ...
func (m *UserServiceDefaultServer) GetUserByName(ctx context.Context, in *GetUserByNameRequest) (*GetUserByNameResponse, error) {
	out := &GetUserByNameResponse{}
	return out, nil
}

// ChangePassword ...
func (m *UserServiceDefaultServer) ChangePassword(ctx context.Context, in *ChangePasswordRequest) (*CreateUserResponse, error) {
	out := &CreateUserResponse{}
	return out, nil
}

// TestDuDu ...
func (m *UserServiceDefaultServer) TestDuDu(ctx context.Context, in *CreateUserRequest) (*CreateUserResponse, error) {
	out := &CreateUserResponse{}
	return out, nil
}

// CreateUser ...
func (m *UserServiceDefaultServer) CreateUser(ctx context.Context, in *CreateUserRequest) (*CreateUserResponse, error) {
	db := m.DB
	if custom, ok := interface{}(in).(UserServiceUserWithBeforeCreateUser); ok {
		var err error
		if db, err = custom.BeforeCreateUser(ctx, db); err != nil {
			return nil, err
		}
	}
	res, err := DefaultCreateUser(ctx, in.GetPayload(), db)
	if err != nil {
		return nil, err
	}
	out := &CreateUserResponse{Result: res}
	if custom, ok := interface{}(in).(UserServiceUserWithAfterCreateUser); ok {
		var err error
		if err = custom.AfterCreateUser(ctx, out, db); err != nil {
			return nil, err
		}
	}
	return out, nil
}

// UserServiceUserWithBeforeCreateUser called before DefaultCreateUserUser in the default CreateUser handler
type UserServiceUserWithBeforeCreateUser interface {
	BeforeCreateUser(context.Context, *gorm.DB) (*gorm.DB, error)
}

// UserServiceUserWithAfterCreateUser called before DefaultCreateUserUser in the default CreateUser handler
type UserServiceUserWithAfterCreateUser interface {
	AfterCreateUser(context.Context, *CreateUserResponse, *gorm.DB) error
}

// Read ...
func (m *UserServiceDefaultServer) Read(ctx context.Context, in *ReadUserRequest) (*ReadUserResponse, error) {
	db := m.DB
	if custom, ok := interface{}(in).(UserServiceUserWithBeforeRead); ok {
		var err error
		if db, err = custom.BeforeRead(ctx, db); err != nil {
			return nil, err
		}
	}
	res, err := DefaultReadUser(ctx, &User{Id: in.GetId()}, db, in.Fields)
	if err != nil {
		return nil, err
	}
	out := &ReadUserResponse{Result: res}
	if custom, ok := interface{}(in).(UserServiceUserWithAfterRead); ok {
		var err error
		if err = custom.AfterRead(ctx, out, db); err != nil {
			return nil, err
		}
	}
	return out, nil
}

// UserServiceUserWithBeforeRead called before DefaultReadUser in the default Read handler
type UserServiceUserWithBeforeRead interface {
	BeforeRead(context.Context, *gorm.DB) (*gorm.DB, error)
}

// UserServiceUserWithAfterRead called before DefaultReadUser in the default Read handler
type UserServiceUserWithAfterRead interface {
	AfterRead(context.Context, *ReadUserResponse, *gorm.DB) error
}

// Update ...
func (m *UserServiceDefaultServer) Update(ctx context.Context, in *UpdateUserRequest) (*UpdateUserResponse, error) {
	var err error
	var res *User
	db := m.DB
	if custom, ok := interface{}(in).(UserServiceUserWithBeforeUpdate); ok {
		var err error
		if db, err = custom.BeforeUpdate(ctx, db); err != nil {
			return nil, err
		}
	}
	if in.GetGerogeriGegege() == nil {
		res, err = DefaultStrictUpdateUser(ctx, in.GetPayload(), db)
	} else {
		res, err = DefaultPatchUser(ctx, in.GetPayload(), in.GetGerogeriGegege(), db)
	}
	if err != nil {
		return nil, err
	}
	out := &UpdateUserResponse{Result: res}
	if custom, ok := interface{}(in).(UserServiceUserWithAfterUpdate); ok {
		var err error
		if err = custom.AfterUpdate(ctx, out, db); err != nil {
			return nil, err
		}
	}
	return out, nil
}

// UserServiceUserWithBeforeUpdate called before DefaultUpdateUser in the default Update handler
type UserServiceUserWithBeforeUpdate interface {
	BeforeUpdate(context.Context, *gorm.DB) (*gorm.DB, error)
}

// UserServiceUserWithAfterUpdate called before DefaultUpdateUser in the default Update handler
type UserServiceUserWithAfterUpdate interface {
	AfterUpdate(context.Context, *UpdateUserResponse, *gorm.DB) error
}

// UpdateSet ...
func (m *UserServiceDefaultServer) UpdateSet(ctx context.Context, in *UpdateSetUserRequest) (*UpdateSetUserResponse, error) {
	if in == nil {
		return nil, errors.NilArgumentError
	}

	db := m.DB

	if custom, ok := interface{}(in).(UserServiceUserWithBeforeUpdateSet); ok {
		var err error
		if db, err = custom.BeforeUpdateSet(ctx, db); err != nil {
			return nil, err
		}
	}

	res, err := DefaultPatchSetUser(ctx, in.GetObjects(), in.GetMasks(), db)
	if err != nil {
		return nil, err
	}

	out := &UpdateSetUserResponse{Results: res}

	if custom, ok := interface{}(in).(UserServiceUserWithAfterUpdateSet); ok {
		var err error
		if err = custom.AfterUpdateSet(ctx, out, db); err != nil {
			return nil, err
		}
	}

	return out, nil
}

// UserServiceUserWithBeforeUpdateSet called before DefaultUpdateSetUser in the default UpdateSet handler
type UserServiceUserWithBeforeUpdateSet interface {
	BeforeUpdateSet(context.Context, *gorm.DB) (*gorm.DB, error)
}

// UserServiceUserWithAfterUpdateSet called before DefaultUpdateSetUser in the default UpdateSet handler
type UserServiceUserWithAfterUpdateSet interface {
	AfterUpdateSet(context.Context, *UpdateSetUserResponse, *gorm.DB) error
}

// List ...
func (m *UserServiceDefaultServer) List(ctx context.Context, in *ListUserRequest) (*ListUserResponse, error) {
	db := m.DB
	if custom, ok := interface{}(in).(UserServiceUserWithBeforeList); ok {
		var err error
		if db, err = custom.BeforeList(ctx, db); err != nil {
			return nil, err
		}
	}
	pagedRequest := false
	if in.GetPaging().GetLimit() >= 1 {
		in.Paging.Limit++
		pagedRequest = true
	}
	res, err := DefaultListUser(ctx, db, in.Filter, in.OrderBy, in.Paging, in.Fields)
	if err != nil {
		return nil, err
	}
	var resPaging *query.PageInfo
	if pagedRequest {
		var offset int32
		var size int32 = int32(len(res))
		if size == in.GetPaging().GetLimit() {
			size--
			res = res[:size]
			offset = in.GetPaging().GetOffset() + size
		}
		resPaging = &query.PageInfo{Offset: offset}
	}
	out := &ListUserResponse{Results: res, PageInfo: resPaging}
	if custom, ok := interface{}(in).(UserServiceUserWithAfterList); ok {
		var err error
		if err = custom.AfterList(ctx, out, db); err != nil {
			return nil, err
		}
	}
	return out, nil
}

// UserServiceUserWithBeforeList called before DefaultListUser in the default List handler
type UserServiceUserWithBeforeList interface {
	BeforeList(context.Context, *gorm.DB) (*gorm.DB, error)
}

// UserServiceUserWithAfterList called before DefaultListUser in the default List handler
type UserServiceUserWithAfterList interface {
	AfterList(context.Context, *ListUserResponse, *gorm.DB) error
}

// Delete ...
func (m *UserServiceDefaultServer) Delete(ctx context.Context, in *DeleteUserRequest) (*DeleteUserResponse, error) {
	db := m.DB
	if custom, ok := interface{}(in).(UserServiceUserWithBeforeDelete); ok {
		var err error
		if db, err = custom.BeforeDelete(ctx, db); err != nil {
			return nil, err
		}
	}
	err := DefaultDeleteUser(ctx, &User{Id: in.GetId()}, db)
	if err != nil {
		return nil, err
	}
	out := &DeleteUserResponse{}
	if custom, ok := interface{}(in).(UserServiceUserWithAfterDelete); ok {
		var err error
		if err = custom.AfterDelete(ctx, out, db); err != nil {
			return nil, err
		}
	}
	return out, nil
}

// UserServiceUserWithBeforeDelete called before DefaultDeleteUser in the default Delete handler
type UserServiceUserWithBeforeDelete interface {
	BeforeDelete(context.Context, *gorm.DB) (*gorm.DB, error)
}

// UserServiceUserWithAfterDelete called before DefaultDeleteUser in the default Delete handler
type UserServiceUserWithAfterDelete interface {
	AfterDelete(context.Context, *DeleteUserResponse, *gorm.DB) error
}

// DeleteSet ...
func (m *UserServiceDefaultServer) DeleteSet(ctx context.Context, in *DeleteUsersRequest) (*DeleteUserResponse, error) {
	db := m.DB
	objs := []*User{}
	for _, id := range in.Ids {
		objs = append(objs, &User{Id: id})
	}
	if custom, ok := interface{}(in).(UserServiceUserWithBeforeDeleteSet); ok {
		var err error
		if db, err = custom.BeforeDeleteSet(ctx, db); err != nil {
			return nil, err
		}
	}
	err := DefaultDeleteUserSet(ctx, objs, db)
	if err != nil {
		return nil, err
	}
	out := &DeleteUserResponse{}
	if custom, ok := interface{}(in).(UserServiceUserWithAfterDeleteSet); ok {
		var err error
		if err = custom.AfterDeleteSet(ctx, out, db); err != nil {
			return nil, err
		}
	}
	return out, nil
}

// UserServiceUserWithBeforeDeleteSet called before DefaultDeleteSetUser in the default DeleteSet handler
type UserServiceUserWithBeforeDeleteSet interface {
	BeforeDeleteSet(context.Context, *gorm.DB) (*gorm.DB, error)
}

// UserServiceUserWithAfterDeleteSet called before DefaultDeleteSetUser in the default DeleteSet handler
type UserServiceUserWithAfterDeleteSet interface {
	AfterDeleteSet(context.Context, *DeleteUserResponse, *gorm.DB) error
}
